package com.wing.product.controller.admin;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wing.common.utils.JsonResult;
import com.wing.common.utils.PageResult;
import com.wing.web.db.config.util.DynamicDataSource;
import com.wing.enterprisecab.feign.EnterpriseCabClient;
import com.wing.enterprisecab.product.model.response.ProductDetailVO;
import com.wing.product.model.entity.ProductPackLabel;
import com.wing.product.model.request.ProductPackLabelForm;
import com.wing.product.model.response.ProductPackLabelVO;
import com.wing.product.service.ProductPackLabelService;
import com.wing.web.annotation.RequestObjectFieldIgnore;
import com.wing.web.utils.JwtUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * @author
 */
@Validated
@Api(value = "Admin-产品包装条码管理", tags = "#/product/productPackLabel")
@RestController("productPackLabelController")
@RequestMapping("product/admin/productPackLabel")
@RequiredArgsConstructor
@Slf4j
public class ProductPackLabelController {

    private final ProductPackLabelService productPackLabelService;
    private final EnterpriseCabClient enterpriseCabClient;

    @ApiOperation(value = "查询所有产品包装条码", notes = "搜索")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "第几页", defaultValue = "1", example = "1", dataType = "Integer", paramType = "query")
            ,@ApiImplicitParam(name = "limit", value = "每页多少条", defaultValue = "10", example = "10", dataType = "Integer", paramType = "query")
            ,@ApiImplicitParam(name = "sort", value="排序字段名", defaultValue = "create_time", example = "create_time", dataType = "String", paramType = "query")
            ,@ApiImplicitParam(name = "order", value="排序规则(asc:正序, desc:倒序)", defaultValue = "desc", example = "desc", dataType = "String", paramType = "query")
            ,@ApiImplicitParam(name = "inventoryType", value="入库类型", defaultValue = "", example = "", dataType = "String", paramType = "query")
            ,@ApiImplicitParam(name = "code", value="包装编码", defaultValue = "", example = "", dataType = "String", paramType = "query")
            ,@ApiImplicitParam(name = "batchCode", value="所属计划单号", defaultValue = "", example = "", dataType = "String", paramType = "query")


    })
    @GetMapping("/list")
    public PageResult<ProductPackLabelVO> list(
            @RequestParam(defaultValue = "1") Integer page
            ,@RequestParam(defaultValue = "10") Integer limit
            ,@RequestParam(defaultValue = "create_time") String sort
            ,@RequestParam(defaultValue = "desc") String order
            ,String inventoryType
            ,String code
            ,String batchCode
            ,Long purchaseSignForId
    ){

        Page<ProductPackLabelVO> pg = new Page<>(page, limit);
        Map<String, Object> params = new HashMap<>();

        //排序
        if (StringUtils.isNotBlank(sort) && StringUtils.isNotBlank(order)) {
            params.put("sort", sort);
            params.put("order", order);
        }
        if(StringUtils.isNotBlank(inventoryType)){
            params.put("inventoryType",inventoryType);
        }
        if(StringUtils.isNotBlank(code)){
            params.put("code",code);
        }
        if(StringUtils.isNotBlank(batchCode)){
            params.put("batchCode",batchCode);
        }
        //搜索
        if(null != purchaseSignForId){
            params.put("purchaseSignForId", purchaseSignForId);
        }

        IPage<ProductPackLabelVO> list = productPackLabelService.pageList4app(pg, params);
        List<ProductPackLabelVO> records = list.getRecords();
        for (ProductPackLabelVO productPackLabelVO: records) {
            productPackLabelVO.setInventoryTypeIdDesc(productPackLabelVO.getInventoryTypeId().getDesc());
        }

        return new PageResult<>(list.getRecords(), list.getTotal());
    }



    @ApiOperation(value = "添加产品包装条码", notes = "添加")
    @RequestObjectFieldIgnore({"id", "createTime", "remark"})
    @PostMapping("/add")
    public JsonResult<ProductPackLabel> add(@Validated(ProductPackLabelForm.Add.class)  @RequestBody ProductPackLabelForm productPackLabelForm) {
        try {

            List<ProductPackLabel> packLabels = productPackLabelService.inertPackIndex(productPackLabelForm);
                return JsonResult.success(packLabels);
        }catch (Exception e) {
            log.error("添加失败",e);
        }
        return JsonResult.fail("添加失败");
    }

    @ApiOperation(value = "添加产品包装条码", notes = "添加")
    @RequestObjectFieldIgnore({"id", "createTime", "remark"})
    @PostMapping("/addNew")
    public JsonResult<ProductPackLabel> addNew(@Validated(ProductPackLabelForm.Add.class) @RequestBody ProductPackLabelForm productPackLabelForm) {
        try {

            List<ProductPackLabel> packLabels = productPackLabelService.inertPackIndex2(productPackLabelForm);
            return JsonResult.success(packLabels);
        }catch (Exception e) {
            log.error("添加失败",e);
        }
        return JsonResult.fail("添加失败");
    }


    /**
     * 条码出库新增
     *
     * @return {@link JsonResult}
     */
    @ApiOperation(value = "条码出库新增", notes = "添加")
    @RequestObjectFieldIgnore({"id", "createTime", "remark"})
    @PostMapping("/extractLabel4InventoryIn")
    public JsonResult<ProductPackLabelForm> extractLabel4InventoryIn(@RequestParam(value = "code") String code,@RequestParam(value = "extract") Integer extract,@RequestParam(value = "addCount") Integer addCount) {
        try {

            ProductPackLabelForm productPackLabel = productPackLabelService.extractLabel4InventoryIn(code, extract, addCount);
            return JsonResult.success(productPackLabel);

        }catch (Exception e) {
            log.error("添加失败",e);
        }
        return JsonResult.fail("添加失败");
    }

    @ApiOperation(value = "条码入库新增", notes = "添加")
    @RequestObjectFieldIgnore({"id", "createTime", "remark"})
    @PostMapping("/extractLabel4InventoryIn2")
    public JsonResult<ProductPackLabelForm> extractLabel4InventoryIn2(@RequestParam(value = "code") String code,@RequestParam(value = "extract") Integer extract,@RequestParam(value = "addCount") Integer addCount,@RequestParam(value = "boxId")Long boxId,@RequestParam(value = "warehouseId")Long warehouseId,@RequestParam(value = "areaId")Long areaId,@RequestParam(value = "shelfId")Long shelfId,@RequestParam(value = "spaceId")Long spaceId) {
        try {

            ProductPackLabelForm productPackLabel = productPackLabelService.extractLabel4InventoryIn(code, extract, addCount,boxId,warehouseId,areaId,shelfId,spaceId);
            return JsonResult.success(productPackLabel);

        }catch (Exception e) {
            log.error("添加失败",e);
            return JsonResult.fail(e.getMessage());
        }
    }

    @ApiOperation(value = "条码出库新增", notes = "添加")
    @RequestObjectFieldIgnore({"id", "createTime", "remark"})
    @PostMapping("/extractLabel4InventoryOut")
    public JsonResult<ProductPackLabelForm> extractLabel4InventoryOut(@RequestParam(value = "code") String code,@RequestParam(value = "extract") Integer extract,@RequestParam(value = "addCount") Integer addCount) {
        try {

            ProductPackLabelForm productPackLabel = productPackLabelService.extractLabel4InventoryOut(code, extract, addCount);
            return JsonResult.success(productPackLabel);

        }catch (Exception e) {
            log.error("添加失败",e);
            return JsonResult.fail("添加失败:"+ e);
        }

    }




    @ApiOperation(value = "修改产品包装条码", notes = "修改")
    @PutMapping("/update")
    public JsonResult update(@Validated(ProductPackLabelForm.Update.class) ProductPackLabelForm productPackLabelForm) {

        ProductPackLabel productPackLabel = productPackLabelService.getById(productPackLabelForm.getId());
        if(productPackLabel == null){
            return JsonResult.fail("修改失败！");
        }
        CopyOptions copyOptions = CopyOptions.create()
                .setEditable(ProductPackLabel.class)
                .setIgnoreError(true)
                .setIgnoreNullValue(true);
        BeanUtil.copyProperties(productPackLabelForm, productPackLabel, copyOptions);
        if (productPackLabelService.updateById(productPackLabel)) {
            return JsonResult.success("修改成功！");
        }
        return JsonResult.fail("修改失败！");
    }



    @ApiOperation(value = "删除产品包装条码", notes = "删除")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "productPackLabelId", value = "产品包装条码id", required = true, dataType = "Integer", paramType = "path")
    })
    @DeleteMapping("/{id}" )
    public JsonResult delete(@PathVariable("id") Long productPackLabelId) {

        if (productPackLabelService.removeById(productPackLabelId)) {
            return JsonResult.success("删除成功");
        }
        return JsonResult.fail("删除失败");
    }

    /**
     * 产品包装标签id
     *
     * @param packLabelId 包装标签id
     * @return {@link JsonResult}<{@link ProductPackLabelVO}>
     */
    @GetMapping("/getProductPackLabelById")
    public JsonResult<ProductPackLabelVO> getProductPackLabelById(Long packLabelId){

        ProductPackLabelVO packLabelVO = productPackLabelService.get4appById(packLabelId);
        return JsonResult.success(packLabelVO);
    }

    /**
     * 产品包装标签volist
     *
     * @param code 代码
     * @param type 用于区分出入库扫描包装条码
     * @return {@link JsonResult}<{@link List}<{@link ProductPackLabelVO}>>
     */
    @GetMapping("/getProductPackLabelVOList")
    public JsonResult<ProductPackLabelVO> getProductPackLabelVOList(String code,Integer type){

        ProductPackLabelVO productPackLabelVO = productPackLabelService.getProductPackLabelVoList(code);
        if(productPackLabelVO != null){
            if(type!=null){
                if(type == 0){//入库扫描包装条码
                    if(productPackLabelVO.getStatus().name().equals("inventoryIn")){
                        return JsonResult.fail("此包装条码已入库，请勿重复扫码");
                    }
                }else{//出库扫描包装条码
                    if(productPackLabelVO.getStatus().name().equals("created")){
                        return JsonResult.fail("此包装条码还未入库");
                    }else if(productPackLabelVO.getStatus().name().equals("inventoryOut")){
                        return JsonResult.fail("此包装条码已出库，请勿重复扫码");
                    }
                }
            }

            //入库类型是签收刀具入库 查询kab库相关产品信息
            if("cutter".equals(productPackLabelVO.getInoutTypeCode())){
                JsonResult<ProductDetailVO> jsonResult = enterpriseCabClient.getProductInfoBySkuCode(productPackLabelVO.getSkuCode());
                ProductDetailVO detailVO = jsonResult.getData();
                productPackLabelVO.setProductName(detailVO.getProductName());
                productPackLabelVO.setUnitName(detailVO.getUnitName());
            }
            return JsonResult.success(productPackLabelVO);
        }else{
            return JsonResult.fail("未找到包装条码");
        }

    }
    @ApiOperation(value = "修改产品包装条码", notes = "修改")
    @PutMapping("/updateProductPackLabel")
    public JsonResult updateProductPackLabel(@RequestBody ProductPackLabelVO productPackLabelVO){

        if(productPackLabelVO == null){
            return JsonResult.fail("修改失败！");
        }
        ProductPackLabel productPackLabel = new ProductPackLabel();
        CopyOptions copyOptions = CopyOptions.create()
                .setEditable(ProductPackLabel.class)
                .setIgnoreError(true)
                .setIgnoreNullValue(true);
        BeanUtil.copyProperties(productPackLabelVO, productPackLabel, copyOptions);
        if (productPackLabelService.updateById(productPackLabel)) {
            return JsonResult.success("修改成功！");
        }
        return JsonResult.fail("修改失败！");


    }

    @ApiOperation(value = "打印条形码")
    @GetMapping("/getBarCode")
    public JsonResult<String> getBarCode(@RequestParam(value = "code") String code){

        String data = productPackLabelService.getBarCode(code);
        return JsonResult.success("true",data);
    }
    @ApiOperation(value = "查询所有出库单计划下的包装条码", notes = "搜索")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "第几页", defaultValue = "1", example = "1", dataType = "Integer", paramType = "query")
            ,@ApiImplicitParam(name = "limit", value = "每页多少条", defaultValue = "10", example = "10", dataType = "Integer", paramType = "query")
            ,@ApiImplicitParam(name = "sort", value="排序字段名", defaultValue = "create_time", example = "create_time", dataType = "String", paramType = "query")
            ,@ApiImplicitParam(name = "order", value="排序规则(asc:正序, desc:倒序)", defaultValue = "asc", example = "asc", dataType = "String", paramType = "query")
    })
    @GetMapping("/getInventoryPackLabelPageList")
    public PageResult<ProductPackLabelVO> list(
            @RequestParam(defaultValue = "1") Integer page
            ,@RequestParam(defaultValue = "10") Integer limit
            ,@RequestParam(defaultValue = "create_time") String sort
            ,@RequestParam(defaultValue = "asc") String order
            ,Long planId
    ){

        //搜索
        IPage<ProductPackLabelVO> list = productPackLabelService.getInventoryPackLabelPageList(page,limit,planId);
        return new PageResult<>(list.getRecords(), list.getTotal());
    }

    /**
     * 扫描包装条码 签收 入库 出库
     * @param planId
     * @param code
     * @param type
     * @return
     */
    @ApiOperation(value = "扫描包装条码", notes = "搜索")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "planId", value = "计划id", required = false, dataType = "Integer", paramType = "path")
            ,@ApiImplicitParam(name = "code", value = "条码编号", required = true, dataType = "String", paramType = "path")
            ,@ApiImplicitParam(name = "type", value = "0:入库扫描 1:出库扫码 2:签收扫码", required = true, dataType = "Integer", paramType = "path")
    })
    @GetMapping("/getPackLabelVOByCode")
    public JsonResult<ProductPackLabelVO> getPackLabelVOByCode(Long planId, String code,Integer type,Long warehouseId){

        ProductPackLabelVO productPackLabelVO = productPackLabelService.getPackLabelVOByCode(planId,code,warehouseId);
        if(productPackLabelVO != null){
            /*if(warehouseId != productPackLabelVO.getWarehouseId()){
                return JsonResult.fail("此包装条码不在当前入库或者出库作业单的仓库中！");
            }*/
            if(type == 0){//入库扫描包装条码
                if(productPackLabelVO.getStatus().name().equals("inventoryIn")){
                    return JsonResult.fail("此包装条码已入库，请勿重复扫码");
                }
            } else if(type == 1){//出库扫描包装条码
                if(productPackLabelVO.getStatus().name().equals("created")){
                    return JsonResult.fail("此包装条码还未入库");
                }else if(productPackLabelVO.getStatus().name().equals("inventoryOut")){
                    return JsonResult.fail("此包装条码已出库，请勿重复扫码");
                }
            }else if(type == 2){//签收扫描包装条码
                if(!productPackLabelVO.getStatus().name().equals("created")){
                    return JsonResult.fail("此包装条码已签收，请勿重复扫码");
                }
            }
            return JsonResult.success(productPackLabelVO);
        }else{
            return JsonResult.fail("未找到包装条码");
        }
    }

    @GetMapping("/getByCode")
    public JsonResult<ProductPackLabelVO> getByCode(String labelCode, Long loadPlanId){

        return productPackLabelService.getByCode(labelCode,loadPlanId);
    }

    @GetMapping("/getLabelByCode")
    public JsonResult<ProductPackLabelVO> getLabelByCode(String labelCode){

        return productPackLabelService.getLabelByCode(labelCode);
    }

    @GetMapping("/getByPurchaseId")
    public JsonResult<List<ProductPackLabel>> getByPurchaseDetailId(@RequestParam("purchaseId")Long purchaseId,@RequestParam("skuCode")String skuCode){

        QueryWrapper<ProductPackLabel>queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("purchase_id",purchaseId);
        queryWrapper.eq("sku_code",skuCode);
        List<ProductPackLabel> labelList = productPackLabelService.list(queryWrapper);
        return JsonResult.success(labelList);
    }
}
